﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using BisinessLogic;
using Domain.Entities;
using Web.ViewModels;


namespace Web.Controllers
{
    [Authorize(Roles = "Moder,Administrator")]
    public class StoreManagerController : Controller
    {
        #region Start
        private DataManager dataManager;
        public StoreManagerController(DataManager dataManager)
        {
            this.dataManager = dataManager;
        }
        public ActionResult Index()
        {
            return View();
        }
        public ActionResult GenreMenu()
        {
            return PartialView();
        }

        #endregion
        #region Role

        [HttpGet]
        public ActionResult BrowseRoles()
        {
            var roles = dataManager.Roles.GetRoles();
            return View(roles);
        }

        [HttpGet]
        public ActionResult CreateRole()
        {
            return View();
        }

        [HttpPost]
        public ActionResult CreateRole(Role role)
        {
            if (ModelState.IsValid)
            {
                dataManager.Roles.SaveRole(role);
                return RedirectToAction("BrowseRoles");
            }
            return View(role);
        }

        [HttpGet]
        public ActionResult EditRole(int id)
        {
            return View(dataManager.Roles.GetRoleById(id));
        }

        [HttpPost]
        public ActionResult EditRole(Role role)
        {
            if (ModelState.IsValid)
            {
                dataManager.Roles.SaveRole(role);
                return RedirectToAction("BrowseRoles");
            }
            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult DeleteRole(int id)
        {
            var role = dataManager.Roles.GetRoleById(id);
            try
            {
                dataManager.Roles.DeleteRoleById(role.Id);
            }
            catch (Exception ex)
            {
                return Json(new { errorMessage = "При обновлении записей возникла ошибка." + "</br>" + ex.InnerException.InnerException.Message, success = false });
            }
            return Json(new { success = true });
        }








        #endregion
        #region User

        public ActionResult BrowseUsers()
        {
            var users = dataManager.Users.GetUsers();
            return View(users);
        }

        [HttpGet]
        public ActionResult EditeUser(int id)
        {
            User user = dataManager.Users.GetUserById(id);
            var query = dataManager.Roles.GetRoles().Select(c => new { c.Id, c.Name });
            ViewBag.RoleId = new SelectList(query.AsEnumerable(), "Id", "Name", user.RoleId);
            return View(dataManager.Users.GetUserById(id));
        }


        // Создаем текст ошибки для MembershipCreateStatus
        private string GetMembershipCreateStatusResultText(MembershipCreateStatus status)
        {
            if (status == MembershipCreateStatus.DuplicateEmail)
            {
                return "Пользователь с таким e-mail  уже сушествует";
            }
            if (status == MembershipCreateStatus.DuplicateUserName)
            {
                return "Пользователь с таким логином  уже сушествует";
            }
            return "Неизвестная ошибка";
        }

        [HttpPost]
        public ActionResult EditeUser(User user)
        {
            if (ModelState.IsValid)
            {
                dataManager.Users.SaveUser(user);

                MembershipCreateStatus status =
                    dataManager.MembershipProvider.UpdateUser(user);



                if (status == MembershipCreateStatus.Success)
                {
                    return RedirectToAction("BrowseUsers");
                }
                ModelState.AddModelError("", GetMembershipCreateStatusResultText(status));

            }
            ViewBag.RoleId = new SelectList(dataManager.Roles.GetRoles(), "Id", "Name", user.RoleId);
            return View(user);
        }

        [HttpGet]
        public ActionResult DetailsUser(int id)
        {
            return View(dataManager.Users.GetUserById(id));
        }

        [AcceptVerbs(HttpVerbs.Post)]

        public ActionResult DeleteUser(int id)
        {
            try
            {
                dataManager.Users.DeleteUserById(id);
            }
            catch (Exception)
            {
                return Json(new { errorMessage = "При  удалении пользователя произошла неизвестная ошибка.", success = false });
            }
            return Json(new { success = true });
        }


        [HttpGet]
        public ActionResult CreateUser()
        {
            var query = dataManager.Roles.GetRoles().Select(c => new { c.Id, c.Name });
            ViewBag.RoleId = new SelectList(query.AsEnumerable(), "Id", "Name");
            return View();
        }

        [HttpPost]
        public ActionResult CreateUser(User model)
        {

            MembershipCreateStatus status = dataManager.MembershipProvider.CreateUser(
                   model.Login, model.Password, model.Email,
                   model.FirstName, model.LastName, model.MiddleName, model.RoleId);


            if (status == MembershipCreateStatus.Success)
            {
                return RedirectToAction("BrowseUsers");
            }
            var query = dataManager.Roles.GetRoles().Select(c => new { c.Id, c.Name });
            ModelState.AddModelError("", GetMembershipCreateStatusResultText(status));
            ViewBag.RoleId = new SelectList(query.AsEnumerable(), "Id", "Name", model.RoleId);

            return View(model);
        }

        #endregion
        #region Producer
        public ActionResult BrowseProducers()
        {
            return View(dataManager.Producers.GetProducers());
        }


        [HttpGet]
        public ActionResult EditeProducer(int id)
        {
            return View(dataManager.Producers.GetProducerById(id));
        }

        [HttpPost]
        public ActionResult EditeProducer(Producer producer)
        {
            if (ModelState.IsValid)
            {
                dataManager.Producers.SaveProducer(producer);
                return RedirectToAction("BrowseProducers");
            }
            return View(producer);
        }

        public ActionResult DeleteProducer(int id)
        {
            try
            {
                dataManager.Producers.DeleteProducerById(id);
            }
            catch (Exception)
            {
                return Json(new { errorMessage = "При  удалении производителя произошла ошибка. Убедитесь, что в каталоге нет товаров, которые произвел данный производитель.", success = false });
            }
            return Json(new { success = true });
        }

        [HttpGet]
        public ActionResult CreateProducer()
        {
            return View();
        }

        [HttpPost]
        public ActionResult CreateProducer(Producer producer)
        {
            if (ModelState.IsValid)
            {
                dataManager.Producers.SaveProducer(producer);
                return RedirectToAction("BrowseProducers");
            }
            return View(producer);
        }
        #endregion
        #region Category
        public ActionResult BrowseCategory()
        {
            return View(dataManager.Categories.GetCategories());
        }

        [HttpGet]
        public ActionResult EditeCategory(int id)
        {
            return View(dataManager.Categories.GetCategoryById(id));
        }

        [HttpPost]
        public ActionResult EditeCategory(Category category)
        {
            if (ModelState.IsValid)
            {
                dataManager.Categories.SaveCategory(category);
                return RedirectToAction("BrowseCategory");
            }
            return View(category);
        }

        [HttpPost]
        public ActionResult DeleteCategory(int id)
        {

            var cat = dataManager.Categories.GetCategoryById(id);
            int countProduce = dataManager.Produces.GetProduces().Count(p => p.CategoryId == id);

            if (countProduce != 0)
            {
                return Json(new
                {
                    errorMessage = "В категории" + cat.Name + " найдено " + countProduce + " ед. товара. " +
                        "Удаление категории " + cat.Name + " возможно только при отсутствии товаров в данной категории.",
                    success = false
                });
            }
            try
            {
                dataManager.Categories.DeleteCategoryById(id);
            }
            catch (Exception)
            {
                return Json(new { errorMessage = "При удалении категории возникла ошибка. Отсутстувет доступ к базе данных", success = false });
            }
            return Json(new { success = true });
        }

        [HttpGet]
        public ActionResult CreateCategory()
        {
            return View(new Category());
        }

        [HttpPost]
        public ActionResult CreateCategory(Category category)
        {
            if (ModelState.IsValid)
            {
                dataManager.Categories.SaveCategory(category);
                return RedirectToAction("BrowseCategory");
            }
            return View(category);
        }
        #endregion
        #region Prepackage
        [HttpGet]
        public ActionResult BrowsePrepackages()
        {

            return View(dataManager.Prepackages.GetPrepackages()
                //.ToList().OrderBy(i=>i.Weight))
                );
        }

        [HttpGet]
        public ActionResult EditePrepackage(int id)
        {
            return View(dataManager.Prepackages.GetPrepackageById(id));
        }

        [HttpPost]
        public ActionResult EditePrepackage(Prepackage prepackage)
        {
            if (ModelState.IsValid)
            {
                if (
                    dataManager.Prepackages.GetPrepackages()
                        .Count(p => p.Weight == prepackage.Weight && p.Id != prepackage.Id) == 0)
                {
                    dataManager.Prepackages.SavePrepackage(prepackage);
                    return RedirectToAction("BrowsePrepackages");
                }
                ModelState.AddModelError("", "Данная упаковка уже существует");
            }
            return View(prepackage);
        }
        [HttpPost]
        public ActionResult DeletePrepackage(int id)
        {
            int countPrepack = dataManager.ProduceInPackages.GetProduceInPackages().Count(p => p.PrepackageId == id);
            var pack = dataManager.Prepackages.GetPrepackageById(id);

            if (countPrepack != 0)
            {
                return Json(new
                {
                    errorMessage = "В данной упаковке на складе " + countPrepack + " ед. продукции. Удаление упаковки " + pack.Weight + "г" +
                                   " возможно только при отсутствии товаров в данной упаковке.",
                    success = false
                });
            }
            try
            {
                dataManager.Prepackages.DeletePrepackageById(id);
            }
            catch (Exception)
            {
                return Json(new { errorMessage = "При удалении упаковки возникла ошибка. Отсутстувет доступ к базе данных", success = false });
            }
            return Json(new { success = true });
        }

        [HttpGet]
        public ActionResult CreatePrepackage()
        {
            return View(new Prepackage());
        }

        [HttpPost]
        public ActionResult CreatePrepackage(Prepackage prepackage)
        {
            if (ModelState.IsValid)
            {


                if (
                    dataManager.Prepackages.GetPrepackages()
                        .Count(p => p.Weight == prepackage.Weight &&
                                    p.Id != prepackage.Id) == 0)
                {

                    dataManager.Prepackages.SavePrepackage(prepackage);
                    return RedirectToAction("BrowsePrepackages");
                }

                ModelState.AddModelError("", "Данная упаковка уже существует");
            }

            return View(prepackage);

        }


        #endregion
        #region Produce
        [HttpGet]
        public ActionResult BrowseProduces()
        {
            List<Produce> lProduces = dataManager.Produces.GetProduces().ToList();
            List<ProduceModel> list = lProduces.Select(produce => new ProduceModel
            {
                Name = produce.Name,
                Category = produce.Category.Name,
                Producer = produce.Producer.Country,
                ProduceId = produce.Id
            }).ToList();

            return View(list);
        }

        [HttpGet]
        public ActionResult EditeProduce(int id)
        {
            Produce produce = dataManager.Produces.GetProduceById(id);
            IEnumerable<UploadFileModel> uploadFiles = GetImages();
            IEnumerable<Category> categories = dataManager.Categories.GetCategories();
            IEnumerable<Producer> producers = dataManager.Producers.GetProducers();
            ViewBag.CategoryId = new SelectList(categories, "Id", "Name", produce.CategoryId);
            ViewBag.ProducerId = new SelectList(producers, "Id", "Country", produce.ProducerId);
            ViewBag.ProductArtUrl = new SelectList(uploadFiles, "Name", "Name", produce.ProductArtUrl);
            return View(produce);
        }
        [HttpPost]
        public ActionResult EditeProduce(Produce produce)
        {

            if (ModelState.IsValid)
            {
                dataManager.Produces.SaveProduce(produce);
                return RedirectToAction("BrowseProduces");
            }
            IEnumerable<UploadFileModel> uploadFiles = GetImages();
            IEnumerable<Category> categories = dataManager.Categories.GetCategories();
            IEnumerable<Producer> producers = dataManager.Producers.GetProducers();
            ViewBag.CategoryId = new SelectList(categories, "Id", "Name", produce.CategoryId);
            ViewBag.ProducerId = new SelectList(producers, "Id", "Country", produce.ProducerId);
            ViewBag.ProductArtUrl = new SelectList(uploadFiles, "Name", "Name", produce.ProductArtUrl);

            return View(produce);
        }

        public ActionResult CreateProduce()
        {
            IEnumerable<UploadFileModel> uploadFiles = GetImages();
            IEnumerable<Category> categories = dataManager.Categories.GetCategories();
            IEnumerable<Producer> producers = dataManager.Producers.GetProducers();
            ViewBag.CategoryId = new SelectList(categories, "Id", "Name");
            ViewBag.ProducerId = new SelectList(producers, "Id", "Country");
            ViewBag.ProductArtUrl = new SelectList(uploadFiles, "Name", "Name", "Нет_фото.png");
            return View();
        }
        [HttpPost]
        public ActionResult CreateProduce(Produce produce)
        {
            if (ModelState.IsValid)
            {
                dataManager.Produces.CreateProduce(produce);
                return RedirectToAction("BrowseProduces");
            }
            IEnumerable<UploadFileModel> uploadFiles = GetImages();
            IEnumerable<Category> categories = dataManager.Categories.GetCategories();
            IEnumerable<Producer> producers = dataManager.Producers.GetProducers();
            ViewBag.CategoryId = new SelectList(categories, "Id", "Name", produce.CategoryId);
            ViewBag.ProducerId = new SelectList(producers, "Id", "Country", produce.ProducerId);
            ViewBag.ProductArtUrl = new SelectList(uploadFiles, "Name", "Name", produce.ProductArtUrl);
            return View(produce);
        }
        [HttpPost]
        public ActionResult DeleteProduce(int id)
        {
            var p = dataManager.Produces.GetProduceById(id);
            int countProduceInStore = dataManager.ProduceInPackages.GetProduceInPackages().Count(i => i.ProduceId == id);

            if (countProduceInStore != 0)
            {
                return Json(new
                {
                    errorMessage = "На складе найдено " + countProduceInStore + " ед. " + p.Name + ". " +
                        "Удаление " + p.Name + " возможно только при отсутствии его  на складе.",
                    success = false
                });
            }
            try
            {
                dataManager.Produces.DeleteProduceById(id);
            }
            catch (Exception)
            {
                return Json(new { errorMessage = "При удалении товара возникла ошибка. Отсутстувет доступ к базе данных", success = false });
            }
            return Json(new { success = true });

        }

        #endregion
        #region storage
        [HttpGet]
        public ActionResult BrowseStorage()
        {
            var lStorege = dataManager.ProduceInPackages.GetProduceInPackages().ToList();
            List<ProduceModel> list = lStorege.OrderBy(i => i.ProduceId).ThenBy(i => i.Prepackage.Weight).Select(cat => new ProduceModel
            {
                Name = cat.Produce.Name,
                Category = cat.Produce.Category.Name,
                Producer = cat.Produce.Producer.Country,
                Package = cat.Prepackage.Weight.ToString(),
                Count = cat.Count,
                Price = cat.Price,
                ProduceInPackageId = cat.Id
            }).ToList();

            return View(list);
        }


        public ActionResult CreateProduceInStorage()
        {
            ProduceInPackage produceInPackage = new ProduceInPackage();

            var prepackages = dataManager.Prepackages.GetPrepackages();
            IEnumerable<Produce> produces = dataManager.Produces.GetProduces();
            ViewBag.PrepackageId = new SelectList(prepackages, "Id", "Weight", produceInPackage.PrepackageId);
            ViewBag.ProduceId = new SelectList(produces, "Id", "Name", produceInPackage.ProduceId);
            return View(produceInPackage);
        }

        [HttpPost]
        public ActionResult CreateProduceInStorage(ProduceInPackage produceInPackage)
        {

            if (ModelState.IsValid)
            {
                dataManager.ProduceInPackages.SaveProduceInPackage(produceInPackage);
                return RedirectToAction("BrowseStorage");
            }
            Produce produce = dataManager.Produces.GetProduceById(produceInPackage.ProduceId);
            var prepackages = dataManager.Prepackages.GetPrepackages();
            IEnumerable<Produce> produces = dataManager.Produces.GetProduces();
            ViewBag.PrepackageId = new SelectList(prepackages, "Id", "Weight", produceInPackage.PrepackageId);
            ViewBag.ProduceId = new SelectList(produces, "Id", "Name", produceInPackage.ProduceId);
            return View(produceInPackage);

        }

        [HttpGet]
        public ActionResult EditeProduceInStorage(int id)
        {
            ProduceInPackage produceInPackage = dataManager.ProduceInPackages.GetProduceInPackageById(id);
            Produce produce = dataManager.Produces.GetProduceById(produceInPackage.ProduceId);
            var prepackages = dataManager.Prepackages.GetPrepackages();
            IEnumerable<Produce> produces = dataManager.Produces.GetProduces();
            ViewBag.PrepackageId = new SelectList(prepackages, "Id", "Weight", produceInPackage.PrepackageId);
            ViewBag.ProduceId = new SelectList(produces, "Id", "Name", produceInPackage.ProduceId);
            return View(produceInPackage);
        }


        [HttpPost]
        public ActionResult EditeProduceInStorage(ProduceInPackage produceInPackage)
        {

            if (ModelState.IsValid)
            {
                dataManager.ProduceInPackages.SaveProduceInPackage(produceInPackage);
                return RedirectToAction("BrowseStorage");
            }
            Produce produce = dataManager.Produces.GetProduceById(produceInPackage.ProduceId);
            var prepackages = dataManager.Prepackages.GetPrepackages();
            IEnumerable<Produce> produces = dataManager.Produces.GetProduces();
            ViewBag.PrepackageId = new SelectList(prepackages, "Id", "Weight", produceInPackage.PrepackageId);
            ViewBag.ProduceId = new SelectList(produces, "Id", "Name", produceInPackage.ProduceId);
            return View(produceInPackage);

        }
        [HttpPost]
        public ActionResult DeleteProduceInStorage(int id)
        {
            var prod = dataManager.ProduceInPackages.GetProduceInPackageById(id);
            try
            {
                dataManager.ProduceInPackages.DeleteProduceInPackageById(prod.Id);
            }
            catch (Exception)
            {
                return Json(new
                {
                    errorMessage = "Произошла ошибка удаления " + prod.Produce.Name + " " + prod.Prepackage.Weight + "г " + "Возможно, отсутствует доступ к базе данных.",
                    success = false
                });
            }
            return Json(new { success = true });
        }


        #endregion
        #region Image

        IEnumerable<UploadFileModel> GetImages()
        {
            string[] extensions = { ".jpg", ".ico", ".png", ".jpeg" };
            string path = AppDomain.CurrentDomain.BaseDirectory + "\\UploadedFiles\\";
            var directory = new DirectoryInfo(path);
            var uploadFiles = directory.GetFiles().Where(f => extensions.Contains(f.Extension)).Select(f => new UploadFileModel
            {
                Name = f.Name,
                FullPatch = f.FullName,
                Patch = "~\\UploadedFiles\\" + f.Name
            }).ToList();
            return uploadFiles;
        }

        public ActionResult BrowseImages()
        {
            List<UploadFileModel> fileModels = GetImages().ToList();
            return View(fileModels);
        }


        [HttpGet]
        public ActionResult UploadImages()
        {
            return View();
        }

        [HttpPost]
        public ActionResult UploadImages(IEnumerable<HttpPostedFileBase> fileUpload)
        {
            if (ModelState.IsValid)
            {

                foreach (var file in fileUpload)
                {
                    if (file == null) continue;
                    string path = AppDomain.CurrentDomain.BaseDirectory + "UploadedFiles";
                    string filename = Path.GetFileName(file.FileName);
                    if (filename != null)
                    {
                        string filePatch = Path.Combine(path, filename);
                        file.SaveAs(filePatch);
                        ResizeImage(filePatch, filePatch, 200, 200, false);
                    }
                }
                return RedirectToAction("BrowseImages");
            }

            return View("UploadImages");
        }

        [HttpPost]
        public ActionResult DeleteImage()
        {
            string name = Request["name"];
            if (String.IsNullOrEmpty(name))
            {
                return Json(new { errorMessage = "Ошибка удаления", success = false });
            }
            string patch = AppDomain.CurrentDomain.BaseDirectory + "UploadedFiles//";
            patch = Path.Combine(patch, name);

            if (System.IO.File.Exists(patch) == false)
            {
                return Json(new { errorMessage = "Ошибка удаления. Изображения " + name + "  не найдено", success = false });
            }

            try
            {
                System.IO.File.Delete(patch);
                var list = dataManager.Produces.GetProduces().Where(i => i.ProductArtUrl == name);
                dataManager.Produces.SetDefultImageToProduces(list, "Нет_фото.png");
            }
            catch (Exception)
            {
                return Json(new { errorMessage = "Ошибка удаления. Нет доступа для удаления " + name, success = false });
            }

            return Json(new { success = true });
        }

        public void ResizeImage(string OrigFile, string NewFile, int NewWidth, int MaxHeight, bool ResizeIfWider)
        {
            System.Drawing.Image FullSizeImage = System.Drawing.Image.FromFile(OrigFile);
            // Ensure the generated thumbnail is not being used by rotating it 360 degrees
            FullSizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
            FullSizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);

            if (ResizeIfWider)
            {
                if (FullSizeImage.Width <= NewWidth)
                {
                    NewWidth = FullSizeImage.Width;
                }
            }

            int NewHeight = FullSizeImage.Height * NewWidth / FullSizeImage.Width;
            if (NewHeight > MaxHeight) // Height resize if necessary
            {
                NewWidth = FullSizeImage.Width * MaxHeight / FullSizeImage.Height;
                NewHeight = MaxHeight;
            }

            // Create the new image with the sizes we've calculated
            System.Drawing.Image NewImage = FullSizeImage.GetThumbnailImage(NewWidth, NewHeight, null, IntPtr.Zero);
            FullSizeImage.Dispose();
            NewImage.Save(NewFile);
        }

        #endregion

    }
}
